স্প্রিং ওআরএম (Spring ORM) মডিউলটি Hibernate এবং JPA-এর মতো ORM টুলগুলোর সাথে ইন্টিগ্রেট করে ডেটাবেস অপারেশনগুলো সহজ করে। Named Queries হলো JPA এবং Hibernate-এর একটি বৈশিষ্ট্য, যা প্রায়শই ব্যবহৃত কুয়েরিগুলোকে পূর্বনির্ধারিত করে ব্যবহারের সুবিধা দেয়। এগুলো কোডের পুনরাবৃত্তি হ্রাস করে এবং কার্যক্ষমতাও বৃদ্ধি করে।
Named Query হলো একটি নির্দিষ্ট SQL বা HQL কুয়েরি, যা @NamedQuery অ্যানোটেশন বা XML কনফিগারেশন ব্যবহার করে সংজ্ঞায়িত করা হয়। এগুলো Entity ক্লাসে প্রি-ডিফাইন করা হয় এবং প্রয়োজন অনুযায়ী রিফারেন্স করা যায়।
Maven প্রজেক্টে Named Queries ব্যবহারের জন্য নিম্নলিখিত ডিপেন্ডেন্সি pom.xml
এ যোগ করতে হবে:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
@NamedQuery
অ্যানোটেশন ব্যবহার করে Named Query সংজ্ঞায়িত করা হয়:
@Entity
@NamedQueries({
@NamedQuery(
name = "Employee.findByDepartment",
query = "SELECT e FROM Employee e WHERE e.department = :department"
),
@NamedQuery(
name = "Employee.findAllWithSalaryAbove",
query = "SELECT e FROM Employee e WHERE e.salary > :salary"
)
})
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "department")
private String department;
@Column(name = "salary")
private double salary;
// Getters and Setters
}
Spring Data JPA এর সাহায্যে Repository ইন্টারফেসে Named Query ব্যবহার করা যায়:
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
@Query(name = "Employee.findByDepartment")
List<Employee> findByDepartment(@Param("department") String department);
@Query(name = "Employee.findAllWithSalaryAbove")
List<Employee> findAllWithSalaryAbove(@Param("salary") double salary);
}
সার্ভিস স্তরে Repository এর মেথড ব্যবহার করা:
@Service
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
public List<Employee> getEmployeesByDepartment(String department) {
return employeeRepository.findByDepartment(department);
}
public List<Employee> getEmployeesWithHighSalary(double salary) {
return employeeRepository.findAllWithSalaryAbove(salary);
}
}
REST API এর মাধ্যমে Named Query থেকে ডেটা রিটার্ন করার উদাহরণ:
@RestController
@RequestMapping("/api/employees")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@GetMapping("/department/{department}")
public List<Employee> getEmployeesByDepartment(@PathVariable String department) {
return employeeService.getEmployeesByDepartment(department);
}
@GetMapping("/salary-above/{salary}")
public List<Employee> getEmployeesWithHighSalary(@PathVariable double salary) {
return employeeService.getEmployeesWithHighSalary(salary);
}
}
Named Query শুধু অ্যানোটেশন নয়, XML ফাইলেও সংজ্ঞায়িত করা যায়। উদাহরণ:
orm.xml
ফাইল:
<entity-mappings>
<named-query name="Employee.findByDepartment">
<query>SELECT e FROM Employee e WHERE e.department = :department</query>
</named-query>
<named-query name="Employee.findAllWithSalaryAbove">
<query>SELECT e FROM Employee e WHERE e.salary > :salary</query>
</named-query>
</entity-mappings>
Spring Configuration এ orm.xml
যুক্ত করতে হবে:
@PersistenceContext
private EntityManager entityManager;
List<Employee> employees = entityManager.createNamedQuery("Employee.findByDepartment", Employee.class)
.setParameter("department", "HR")
.getResultList();
Spring ORM এবং Named Queries ব্যবহার করে প্রি-ডিফাইন্ড এবং কার্যক্ষম কুয়েরি পরিচালনা করা যায়, যা ডেটাবেস অপারেশনগুলোকে সহজ ও কার্যকর করে। Named Queries কোডের রিডেবিলিটি ও রিইউজেবিলিটি বাড়ায়, যা বড় অ্যাপ্লিকেশনগুলোর জন্য অত্যন্ত উপযোগী।
Named Query (নেমড কুয়েরি) হল Hibernate বা JPA-তে পূর্বনির্ধারিত SQL বা HQL স্টেটমেন্ট যা একটি নির্দিষ্ট নাম দিয়ে সংজ্ঞায়িত করা হয়। এটি ডাটাবেস অপারেশনকে আরও কার্যকরী এবং পুনঃব্যবহারযোগ্য করতে ব্যবহৃত হয়। Named Query সরাসরি Entity ক্লাসে বা Mapping ফাইলে সংজ্ঞায়িত করা যেতে পারে এবং প্রয়োজনে ডাটাবেস অপারেশনের জন্য ডাকা যায়।
Hibernate বা JPA-তে Named Query সাধারণত এভাবে সংজ্ঞায়িত হয়:
@NamedQuery(
name = "Employee.findByDepartment",
query = "FROM Employee WHERE department = :department"
)
<hibernate-mapping>
<class name="com.example.model.Employee" table="employees">
<query name="Employee.findByDepartment">
<![CDATA[FROM Employee WHERE department = :department]]>
</query>
</class>
</hibernate-mapping>
Named Query একবার সংজ্ঞায়িত হলে অ্যাপ্লিকেশনের যেকোনো জায়গা থেকে পুনরায় ব্যবহার করা যায়। এটি কোড পুনর্লিখনের প্রয়োজনীয়তা দূর করে।
ডাটাবেসের জন্য প্রয়োজনীয় কুয়েরিগুলো Entity বা Mapping ফাইলেই সংজ্ঞায়িত থাকে। এর ফলে কোড এবং কুয়েরি বিচ্ছিন্ন থাকে, যা কোডের রক্ষণাবেক্ষণ সহজ করে।
Named Query সাধারণত ডাটাবেস লেভেলে কম্পাইল করা হয় এবং পরে ক্যাশে রাখা হয়। ফলে একই কুয়েরি বারবার চললেও সেটি দ্রুত কার্যকর হয়।
Named Query-এর সিনট্যাক্স শুরুতেই চেক করা হয়, যা runtime এ কুয়েরি-সম্পর্কিত ত্রুটি কমায়।
Named Query ব্যবহারে সরাসরি SQL Injection প্রতিরোধ করা যায়, কারণ এটি ব্যবহারকারীর সরাসরি ইনপুট থেকে Query তৈরি করে না।
package com.example.model;
import jakarta.persistence.*;
@Entity
@NamedQueries({
@NamedQuery(
name = "Employee.findByDepartment",
query = "FROM Employee WHERE department = :department"
),
@NamedQuery(
name = "Employee.findBySalaryGreaterThan",
query = "FROM Employee WHERE salary > :salary"
)
})
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "department")
private String department;
@Column(name = "salary")
private Double salary;
// Getters and Setters
}
DAO বা সার্ভিস লেয়ারে Named Query ব্যবহার করা হয়:
package com.example.dao;
import com.example.model.Employee;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class EmployeeDao {
@Autowired
private SessionFactory sessionFactory;
public List<Employee> findByDepartment(String department) {
Session session = sessionFactory.getCurrentSession();
return session.createNamedQuery("Employee.findByDepartment", Employee.class)
.setParameter("department", department)
.getResultList();
}
public List<Employee> findBySalaryGreaterThan(Double salary) {
Session session = sessionFactory.getCurrentSession();
return session.createNamedQuery("Employee.findBySalaryGreaterThan", Employee.class)
.setParameter("salary", salary)
.getResultList();
}
}
Named Query ব্যবহার করে ডাটাবেস অপারেশন করা:
package com.example;
import com.example.service.EmployeeService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
EmployeeService employeeService = context.getBean(EmployeeService.class);
// Named Query ব্যবহার
System.out.println("Employees in IT Department:");
employeeService.findByDepartment("IT").forEach(emp ->
System.out.println(emp.getName())
);
System.out.println("Employees with Salary > 50000:");
employeeService.findBySalaryGreaterThan(50000.0).forEach(emp ->
System.out.println(emp.getName())
);
context.close();
}
}
Named Query ডাটাবেস অপারেশনের নির্ভরযোগ্যতা বৃদ্ধি এবং কোড মডুলার করতে অত্যন্ত কার্যকর।
@NamedQuery একটি জাভা পার্সিস্টেন্স এপিআই (JPA) এর অংশ, যা পূর্ব-সংজ্ঞায়িত (predefined) হাইকিউএল (HQL) বা জেপিকিউএল (JPQL) কোয়েরি তৈরি এবং ব্যবহারের জন্য ব্যবহৃত হয়। এটি সাধারণত Entity ক্লাসের উপরে ডিফাইন করা হয় এবং ডাটাবেজ অপারেশনগুলো আরও কার্যকর করে।
Spring ORM এবং Hibernate-এর মাধ্যমে @NamedQuery ব্যবহার করা হলে, এটি ডাটাবেজ কোয়েরি সহজতর এবং পুনঃব্যবহারযোগ্য করে তোলে।
@NamedQuery(
name = "queryName",
query = "HQL/JPQL_statement"
)
নিচে @NamedQuery
এর একটি সাধারণ উদাহরণ দেওয়া হলো যেখানে User
নামক একটি Entity ক্লাসে এটি ব্যবহৃত হয়েছে।
package com.example.model;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
@Entity
@NamedQuery(
name = "User.findByName",
query = "FROM User WHERE name = :name"
)
public class User {
@Id
private int id;
private String name;
private String email;
// Getters and Setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
@NamedQuery কে Hibernate এর Session বা JPA এর EntityManager এর মাধ্যমে কল করা যায়।
package com.example.dao;
import com.example.model.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import javax.persistence.Query;
import java.util.List;
@Repository
public class UserDao {
@Autowired
private SessionFactory sessionFactory;
public List<User> findUserByName(String name) {
Session session = sessionFactory.getCurrentSession();
Query query = session.getNamedQuery("User.findByName");
query.setParameter("name", name);
return query.getResultList();
}
}
package com.example.service;
import com.example.dao.UserDao;
import com.example.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserDao userDao;
public List<User> getUsersByName(String name) {
return userDao.findUserByName(name);
}
}
package com.example;
import com.example.config.AppConfig;
import com.example.model.User;
import com.example.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.util.List;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = context.getBean(UserService.class);
List<User> users = userService.getUsersByName("John Doe");
users.forEach(user -> {
System.out.println("ID: " + user.getId());
System.out.println("Name: " + user.getName());
System.out.println("Email: " + user.getEmail());
});
}
}
:parameterName
এর মাধ্যমে ডাইনামিক প্যারামিটার সেট করা যায়।@NamedQuery এনোটেশন ব্যবহার করে কোয়েরি অপারেশন আরও কার্যকর এবং পুনঃব্যবহারযোগ্য করা যায়। এটি Spring ORM এবং Hibernate এর সাথে ডাটাবেজ ইন্টিগ্রেশনকে সহজ করে তোলে।
Named Queries হলো পূর্বনির্ধারিত (predefined) SQL বা JPQL (Java Persistence Query Language) স্টেটমেন্ট যা JPA বা Hibernate-এর মাধ্যমে ব্যবহৃত হয়। এগুলো সাধারণত Entity Class-এ সংজ্ঞায়িত থাকে এবং পুনরাবৃত্তিক কোড এড়াতে সাহায্য করে।
Named Queries ব্যবহার করলে অ্যাপ্লিকেশন কোড থেকে কোয়ারি আলাদা থাকে, যা কোডের রিডেবিলিটি এবং রিইউজেবিলিটি বৃদ্ধি করে।
Named Queries সাধারণত @NamedQuery অথবা @NamedQueries এনোটেশন ব্যবহার করে সংজ্ঞায়িত করা হয় এবং এটি Entity ক্লাসের উপর নির্দিষ্ট থাকে।
@Entity
@NamedQuery(
name = "User.findByUsername",
query = "SELECT u FROM User u WHERE u.username = :username"
)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String email;
// Getters and Setters
}
@Entity
@NamedQueries({
@NamedQuery(
name = "User.findAll",
query = "SELECT u FROM User u"
),
@NamedQuery(
name = "User.findByEmail",
query = "SELECT u FROM User u WHERE u.email = :email"
)
})
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String email;
// Getters and Setters
}
Entity ক্লাসে Named Query সংজ্ঞায়িত করতে হবে (উপরের উদাহরণ অনুসরণ করে)।
EntityManager বা Spring Data JPA ব্যবহার করে Named Query কল করা যায়।
@Service
public class UserService {
@Autowired
private EntityManager entityManager;
public User findByUsername(String username) {
return entityManager.createNamedQuery("User.findByUsername", User.class)
.setParameter("username", username)
.getSingleResult();
}
}
Spring Data JPA স্বয়ংক্রিয়ভাবে Named Query সনাক্ত করতে পারে যদি রেপোজিটরি মেথডের নাম Named Query এর নামের সঙ্গে মিলে যায়।
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
}
স্প্রিং ORM Named Queries সহজভাবে ব্যবহার করার জন্য প্রয়োজনীয় EntityManager এবং Spring Data JPA ইন্টিগ্রেশন প্রদান করে। এটি ডেভেলপারদের জন্য কোড পরিষ্কার এবং রিইউজেবল রাখতে সহায়তা করে।
Read more